#include "app_pool.h"
#include "log.h"
#include <mqueue.h>
#include <pthread.h>
#include <stdlib.h>

static  pthread_t *thread_pool;
static  mqd_t mqd;
static  int thread_pool_num;

/**
 * @brief 线程的工作：每个线程主动的去争抢任务，获得任务以后执行任务

 */
void *thread_func(void *arg)
{	while(1)
	{	
	  task_t task;
   	  //1 每个线程主动的去争抢任务
	  mq_receive(mqd,(char *) &task, sizeof(task_t),NULL);
	  //2 获得任务以后执行任务
	  if(task.func != NULL)
	  {
			task.func(task.arg);//用方法执行参数
	  }
	  
   }
}

/**
 * @brief 线程池的初始化 1  初始化队列  2  初始化线程
 */
int app_pool_init(int thread_num)
{
	  //1  初始化队列
	// 1.1 设定队列属性
	struct mq_attr attr;
	attr.mq_maxmsg = 10;
	attr.mq_msgsize = sizeof(task_t);
	// 1.2 创建队列
	 mqd = mq_open(MQUEUE_QUEUE_NAME, O_RDWR | O_CREAT, 0644, &attr);
	 if(mqd == -1)
	 {
		 perror("创建队列失败");
		 return -1;
	 }
	  //2  初始化线程
	  thread_pool_num=thread_num;
	  thread_pool=malloc(sizeof(pthread_t)*thread_num);
	  for(int i=0;i<thread_num;i++)
	  {
		 int ret=  pthread_create(&thread_pool[i],NULL,thread_func,NULL);
		 if(ret==-1)
		 {
			 perror("创建线程失败");
			 return -1;
		 }
	  }

	  return 0;
}

/**
 * @brief 向线程池中添加任务
 * //把 需求方的任务定义和参数 组合为 一个任务结构体
    // 把任务提交到队列中
 */
int app_pool_register_task(void*(*task_func)(void *),void* arg  )
{	
     //1把 需求方的任务定义和参数 组合为 一个任务结构体
	 task_t task;
	 task.func=task_func;
	 task.arg=arg;
    // 2 把任务提交到队列中
     int ret =mq_send(mqd,(char *)&task,sizeof(task),0);
	if (ret == -1)	
	{
		 log_error("加入线程池队列失败");
		 return -1;
	}
	return 0;
	

}

/**
 * @brief 线程池的销毁
 */
void app_pool_destroy()
{
	//1 销毁线程
	for (int i = 0; i < thread_pool_num; i++)
	{
		pthread_cancel(thread_pool[i]);
		pthread_join(thread_pool[i],NULL);
	}
	// 2 销毁队列
	mq_close(mqd);
	mq_unlink(MQUEUE_QUEUE_NAME);

}